package eduware.util;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.Vector;

/**
 * 
 * @author Florian Bausch
 * 
 */
public class WindowTitleList extends Thread {

	/**
	 * Stores all window titles that will not be recognised by
	 * <code>WindowTitleList<code>.
	 */
	private final static Vector<String> OSTITLES = new Vector<String>();
	static {
		OSTITLES.add("Default IME");
		OSTITLES.add("MSCTFIME UI");
		OSTITLES.add("Start menu");
		OSTITLES.add("Start");
		OSTITLES.add("Task Switching");
		OSTITLES.add("CiceroUIWndFrame");
		OSTITLES.add("Battery Meter");
		OSTITLES.add("HiddenFaxWindow");
		OSTITLES.add("Program Manager");
		OSTITLES.add("MCI command handling window");
		OSTITLES.add("nsAppShell:EventWindow");
		OSTITLES.add("TF_FloatingLangBar_WndTitle");
		OSTITLES.add("BluetoothNotificationAreaIconWindowClass");
		OSTITLES.add("Task Host Window");
		OSTITLES.add("DWM Notification Window");
	}

	private Vector<String> windowTitleList = null;
	private int titleCount = 0;
	private int refreshInterval;

	public WindowTitleList(int refreshInterval) {
		this.refreshInterval = refreshInterval;
	}

	public void run() {
		while (true) {
			createWindowTitleList();
			try {
				sleep(this.refreshInterval * 1000);
			} catch (InterruptedException e) {
				return;
			}
		}
	}

	/**
	 * Use this method to get the number of window titles that are stored by
	 * this object. If it is <code>0</code> an error occurred during generating
	 * the window title list or the list is not yet generated.
	 * 
	 * @return An <code>int</code> that indicates the number of windows.
	 */
	public synchronized int getWindowNumbers() {
		return this.titleCount;
	}

	/**
	 * Returns a Vector (String) with the window titles of all open windows
	 * (except system windows).
	 * 
	 * @param renewList
	 *            Indicates whether the window title list shall be refreshed by
	 *            this method
	 * @return Vector (String)
	 */
	public synchronized Vector<String> getWindowTitles(boolean renewList) {
		if (renewList)
			createWindowTitleList();
		return this.windowTitleList;
	}

	/**
	 * Searches in all window titles for the passed strings.
	 * 
	 * @param phrases
	 *            List of strings that are searched in the window titles.
	 * @return <code>true</code>, if the strings in <code>phrases</code> could
	 *         be found in one single window title, <code>false</code>, if not
	 */
	public synchronized boolean windowTitleContains(String... phrases) {
		Iterator<String> iter = this.windowTitleList.iterator();
		String temp;
		int i;
		boolean flag;
		for (i = 0; i < phrases.length; i++)
			phrases[i] = phrases[i].toUpperCase();
		while (iter.hasNext()) {
			temp = iter.next().toUpperCase();
			flag = true;
			for (i = 0; i < phrases.length; i++) {
				if (!temp.contains(phrases[i]))
					flag = false;
			}
			if (flag)
				return true;
		}
		return false;
	}

	/**
	 * Searches in all window titles for the passed string.
	 * 
	 * @param phrase
	 *            String that is searched in the window titles.
	 * @return <code>true</code>, if the string in <code>phrase</code> could be
	 *         found in one single window title, <code>false</code>, if not
	 */
	public synchronized boolean windowTitleContains(String phrase) {
		Iterator<String> iter = this.windowTitleList.iterator();
		String temp;
		phrase = phrase.toUpperCase();
		while (iter.hasNext()) {
			temp = iter.next().toUpperCase();
			if (temp.contains(phrase))
				return true;
		}
		return false;
	}

	/**
	 * Creates a list of window titles by calling <b>Winowtitle.exe</b> that
	 * must be located within the <code>System.getProperty("user.dir")</code>.
	 * <p>
	 * Some window titles will not be recognised because they belong to OS
	 * applications. The list of these titles is stored in <code>OSTITLES</code>
	 * .
	 * </p>
	 */
	public synchronized void createWindowTitleList() {
		Vector<String> v = new Vector<String>();
		int titleCount = 0;
		try {
			String line;
			// Call the Windowtitle.exe
			Process p = Runtime.getRuntime().exec(
					System.getProperty("user.dir") + "\\" + "Windowtitle.exe");
			// Read the result
			BufferedReader input = new BufferedReader(new InputStreamReader(
					p.getInputStream()));

			// Run through the lines and add non-empty lines to v
			while ((line = input.readLine()) != null) {
				line = line.trim();
				if (!line.equals("") && !OSTITLES.contains(line)) {
					v.add(line);
					titleCount++;
				}
			}
			input.close();
			this.windowTitleList = v;
			this.titleCount = titleCount;
		} catch (Exception err) {
			err.printStackTrace();
			this.windowTitleList = null;
			this.titleCount = 0;
		}
	}
}
